//面向过程、面向函数
//函数式编程

//命令式编程：原生js开发或jquery通过操作DOM对象来完成数据的更改
// 声明式编程：框架底层已经封装好模块帮助我们完成DOM的操作，只需去声明即可使用 vue react angular
// 编程范式：命令式编程与声明式编程
// 编程范式：面向对象的编程与面向过程的编程
// 面向过程方式第一个公民即函数，函数式编程

const nums = [10, 20, 111, 222, 444, 40, 50];
//1.从nums数组中取出小于100的数
let newNums = [];
for (const n of nums) {
  if (n < 100) {
    newNums.push(n);
  }
}
console.log(newNums);

//2.从（1）要求中小于100的数都乘以2
let newNewNums = [];
for (const n of newNums) {
  newNewNums.push(n * 2);
}
console.log(newNewNums);

//3.从（2）要求把所有数累加，得到最终结果
let total = 0;
for (const n of newNewNums) {
  total += n;
}
console.log(total);

//封装了一些函数来实现上面的一些效果
//1）filter函数的使用
//参数是一个回调函数，数组有多少个成员，就回调多少次
let newNums1 = nums.filter(function (n) {
  //匿名函数中，有一个参数n，是每一次回调的数组成员，第一次n为10，第二次就为第二个成员
  //匿名函数必须返回的是布尔值，true返回n进入到新的数组中
  return n < 100;
});
console.log(newNums1);

//2）map函数的使用
//它可以对数组中每个内容进行操作
//参数为匿名回调函数
let newNewNums1 = newNums1.map(function (n) {
  //参数为n,指代每次回调的数组成员
  return n * 2;
});
console.log(newNewNums1);

//3）reduce函数，第一个参数为匿名回调函数，第二个参数为默认值
//作用就对数组中所有内容进行汇总
let total1 = newNewNums1.reduce(function (preValue, n) {
  //匿名回调函数中，第一个参数preValue指代上一次返回的值
  //第二个参数为n,本次回调进入的数组成员
  return preValue + n;
}, 0);
console.log(total1);

//把三个需求进行综合，一起提出
let totalnums = nums
  .filter(function (n) {
    return n < 100;
  })
  .map((n) => {
    return n * 2;
  })
  .reduce((preValue, n) => {
    return preValue + n;
  }, 0);
console.log(totalnums);

//es6 语法 匿名函数 箭头函数
//简写规则
//1）参数若为1，可省略括号
//2）函数体中有且只有一行return代码，可以省略大括号和return关键字
let totalnums2 = nums
  .filter(n => n < 100)
  .map(n => n * 2)
  .reduce((preValue, n) => preValue + n, 0);
console.log(totalnums2);
